
struct AttackResult
{
    int hit ;
    int attack ;
    int attack_type ;
    int buff ;

} ;


class FightUnit
{
public:
    virtual ~FightUnit() {} ;

    virtual void on_prepare() ; 
    virtual void on_attack() ;
    virtual void on_defend() ;
    virtual void on_hurt() ;
    virtual void on_dead() ;

    virtual void on_status() ;

} ;


class FightGround
{
public:
    void fight(vector<FightUnit*>& a,vector<fightUnit*>& b) ;

    bool finish() ;
    
    void calc_attack_result(FightUnit* unit,AttackResult* result) ;
    void calc_defend_result(FightUnit* unit,AttackResult* result) ;

    void set_unit_alive_bit(int pos,bool flag) ;

    
} ;

void FightGround::fight(vector<FightUnit*>& a,vector<fightUnit*>& b)
{
    for(auto unit:a) 
    {
        unit->on_prepare() ;
        set_unit_alive_bit(unit->get_pos(),true) ;
    }

    for(auto unit:b)
    { 
        unit->on_prepare() ;
        set_unit_alive_bit(unit->get_pos(),true) ;
    }
    
    while ( ! finish() )
    {
        FightUnit* attack_unit = choose_attack_unit() ;
        FightUnit* defend_unit = choose_defend_unit() ;
        attack_unit->on_attack() ;
        defend_unit->on_defend() ;

        AttackResult result = {0} ;
        calc_attack_result(attack_unit,&result) ;
        calc_defend_result(defend_unit,&result) ;
        
        if(result.hurt > 0 )
        {
            defend_unit->sub_hp(result.hurt) ;
            defend_unit->on_hurt(result.hurt) ;
        }

        if(defend_unit->get_hp() <=0)
        {
            set_unit_alive_bit(define_unit->get_pos(),false) ;
            defend_unit->on_dead() ;
        }
        else
        {

            if(result.buff > 0 )
            {
                defend_unit->on_buff(result.buff) ;
            }

        }


        
    
    }
}


